
#import "VideoRecorderController.h"
#import <AVFoundation/AVFoundation.h>
#import "VideoRecorderView.h"
#import "APGCDTimer.h"

typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);

@interface VideoRecorderController ()<AVCaptureFileOutputRecordingDelegate,UIAlertViewDelegate,CAAnimationDelegate>
{
    BOOL _isRemovePath;
    __block NSString *_videoFileName;
    __block NSString *_videoFilePath;
    APGCDTimer *_timer;
    bool _isCancel;
}
@property (nonatomic, strong) AVCaptureSession *captureSession;//负责输入输出制备之间的数据
@property (nonatomic, strong) AVCaptureDeviceInput *captureDeviceInput;//负责从AVCAptureDevice获得输入数据
@property (nonatomic, strong) AVCaptureMovieFileOutput *captureMovieFileOuput;//视频输出流
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *captureVideoPreViewLayer;//视频预览图层
//@property (nonatomic, assign) BOOL enableRotation;//是否允许旋转
@property (nonatomic, assign) CGRect lastBounds;//旋转钱的大小
@property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;//后台任务标识
@property (nonatomic, strong) VideoRecorderView *videoMainView;
@property (nonatomic, strong) UIImageView *topImageView;
@property (nonatomic, copy) recordVideoDidFinishedBlock finishRecordBlock;



 
@end

@implementation VideoRecorderController

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        self.modalPresentationStyle = UIModalPresentationFullScreen;
        self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        _isRemovePath = NO;
        _videoFilePath = nil;
    }
    return self;
}

- (UIImageView *)topImageView{
    if (!_topImageView) {
        _topImageView = [[UIImageView alloc] init];
        _topImageView.image = [UIImage imageNamed:@"video_recorder_header"];
    }
    return _topImageView;
}

- (VideoRecorderView *)videoMainView{
    if (!_videoMainView) {
        _videoMainView = [[VideoRecorderView alloc] init];
        [_videoMainView.controlView.progressControl.cancelButton addTarget:self action:@selector(videoMainViewCancelButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        [_videoMainView.controlView.progressControl.sureButton addTarget:self action:@selector(videoMainViewSureButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        [_videoMainView.controlView.recordControl.recorderButton addTarget:self action:@selector(videoMainViewStartRecordButtonAction:) forControlEvents:UIControlEventTouchUpInside];

    }
    return _videoMainView;
}


- (void)viewDidLoad {
    [super viewDidLoad];
    [self loadNaviBar2];
    [self loadBackground:@"publish_bg"];
    [self.view addSubview:self.videoMainView];
    [self.videoMainView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.naviBar.mas_bottom);
        make.left.right.bottom.equalTo(self.view);
    }];
}




- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
//    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}


- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [self setUp];

}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
//    [[UIApplication sharedApplication] setStatusBarHidden:NO];

}

- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self.captureSession stopRunning];
    });
}

- (void)videoMainViewSureButtonAction:(UIButton *)sender{
    [self stopRecordingVideoAction];
}

- (void)videoMainViewCancelButtonAction:(UIButton *)sender{
    _isCancel = true;
    self.videoMainView.controlView.progressControl.hidden = true;
    self.videoMainView.controlView.recordControl.hidden = false;
    [self stopRecordingVideoAction];
}

- (void)videoMainViewStartRecordButtonAction:(UIButton *)sender{
    _isCancel = false;
    _isRemovePath = NO;
    WS(ws);
    [self videoRecorderStartRecord];
    _timer = [[APGCDTimer alloc] init];
    __block CGFloat count = 10;
    self.videoMainView.controlView.progressControl.hidden = false;
    self.videoMainView.controlView.recordControl.hidden = true;
    [_timer startTimerWithEventHandler:^{
        count--;
        [ws updateProgress:count];
        if (count == 0) {
            LYLog(@"----------%f",count);
            [ws stopRecordingVideoAction];
        }
    }];
    
}

- (void)updateProgress:(CGFloat)progress{
    self.videoMainView.controlView.progressControl.progress = progress;
    
}


- (void)setUp{    
    
    if (![APAuthorizationManager canUseCaptureDevice]) {
        [self.view ShowProgressOnlyLabel:@"You have not authorised this permission."];
        return;
    }
    AVAuthorizationStatus Status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    if (Status == AVAuthorizationStatusRestricted || Status == AVAuthorizationStatusDenied) {
        [self.view ShowProgressOnlyLabel:@"You have not authorised this permission."];
        return;
    }
    //初始化会话
    _captureSession = [[AVCaptureSession alloc] init];
    //获取输入设备
    AVCaptureDevice *captureDevice = [self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//获取后置摄像头
    if (!captureDevice) {
        return;
    }
    AVCaptureDevice *audioCaptureDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
    NSError *error = nil;
    //根据设备初始化设备输入对象,用于获得输入数据
    _captureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:captureDevice error:&error];
    if (error) {
        return;
    }
    
    AVCaptureDeviceInput *audioCaptureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:audioCaptureDevice error:&error];
    if (error) {
        return;
    }
    //初始化设备输出对象,用于获取输出数据
    _captureMovieFileOuput = [[AVCaptureMovieFileOutput alloc] init];
    //将设备输入添加到会话中
    if ([_captureSession canAddInput:_captureDeviceInput]) {
        [_captureSession addInput:_captureDeviceInput];
    }
    if ([_captureSession canAddInput:audioCaptureDeviceInput]) {
        [_captureSession addInput:audioCaptureDeviceInput];
    }
    AVCaptureConnection *captureConnection = [_captureMovieFileOuput connectionWithMediaType:AVMediaTypeVideo];
    if ([captureConnection isVideoStabilizationSupported]) {
        captureConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
    }

    //创建视频预览层,用于实时展示摄像头状态
    _captureVideoPreViewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
    captureConnection.videoOrientation = _captureVideoPreViewLayer.connection.videoOrientation;
    
    //将设备输出添加到会话中
    if ([_captureSession canAddOutput:_captureMovieFileOuput]) {
        [_captureSession addOutput:_captureMovieFileOuput];
    }
    
    CALayer *layer = self.videoMainView.viewContainer.layer;
    layer.masksToBounds = YES;
    _captureVideoPreViewLayer.frame = layer.bounds;
    _captureVideoPreViewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//填充模式
    [layer addSublayer:_captureVideoPreViewLayer];
//    [layer insertSublayer:_captureVideoPreViewLayer above:self.videoMainView.fousCursor.layer];
    //    _enableRotation = YES;
//    [self addNotificationToCaptureDevice:captureDevice];
//    [self addGestureRecongnizer];
    [self performSelectorInBackground:@selector(startCaptureSessionRunning) withObject:nil];
}

- (void)startCaptureSessionRunning{
    [self.captureSession startRunning];

}


//- (BOOL)shouldAutorotate{
//    return YES;
//}
//
//- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
//    AVCaptureConnection *captureConnection = [self.captureVideoPreViewLayer connection];
//    captureConnection.videoOrientation = (AVCaptureVideoOrientation)toInterfaceOrientation;
//    
//}
//
//- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
//    _captureVideoPreViewLayer.frame = self.viewContainer.bounds;
//}


#pragma mark 视频录制
-(void)drawLineToPoint:(CGPoint)point view:(UIView *)view;
{
    UIBezierPath *path=[UIBezierPath bezierPath];
    [path moveToPoint:point];
    [path addLineToPoint:CGPointMake(self.view.frame.size.width *0.5, 1)];
    CAShapeLayer *arcLayer=[CAShapeLayer layer];
    arcLayer.path=path.CGPath;
    arcLayer.fillColor=[UIColor colorWithRed:253/255.0 green:113/255.0 blue:142/255.0 alpha:1].CGColor;
    arcLayer.strokeColor=[UIColor colorWithRed:253/255.0 green:113/255.0 blue:142/255.0 alpha:1] .CGColor;
    arcLayer.lineWidth=2;
    arcLayer.frame=self.view.frame;
    [view.layer addSublayer:arcLayer];
    [self drawLineAnimation:arcLayer];
    
    
}
-(void)drawLineAnimation:(CALayer*)layer
{
    CABasicAnimation *bas=[CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    bas.duration=10;
    bas.delegate=self;
    bas.fromValue=[NSNumber numberWithInteger:0];
    bas.toValue=[NSNumber numberWithInteger:1];
    [layer addAnimation:bas forKey:@"key"];
}



- (void)stopRecordingVideoAction{
    [self.captureMovieFileOuput stopRecording];//停止录制
    [_timer stopTimer];

}



- (void)videoRecorderStartRecord{
    //根据设备输出获得连接
    AVCaptureConnection *captureConnection = [self.captureMovieFileOuput connectionWithMediaType:AVMediaTypeVideo];
    //根据连接取得设备输出的数据
    LYLog(@"-------%d",self.captureMovieFileOuput.isRecording);
    if (![self.captureMovieFileOuput isRecording]) {
//        self.enableRotation = NO;
        //如果支持多任务规则 开始多任务
        if ([[UIDevice currentDevice] isMultitaskingSupported]) {
            self.backgroundTaskIdentifier = [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:nil];
        }
        //预览图层和视频方向保持一致
        captureConnection.videoOrientation = [self.captureVideoPreViewLayer connection].videoOrientation;
        NSDate *currentDate = [NSDate date];
        long int timeStamp = lround(floor([currentDate timeIntervalSince1970]));
        NSString *videoFileName = [NSString stringWithFormat:@"movie_%ld.mov",timeStamp];
        NSString *outputFilePath = [NSString stringWithFormat:@"%@/%@",VIDEO_RECORDFILE_FOLDER_PATH,videoFileName];
        if (![[NSFileManager defaultManager] fileExistsAtPath:VIDEO_RECORDFILE_FOLDER_PATH]) {
            [[NSFileManager defaultManager] createDirectoryAtPath:VIDEO_RECORDFILE_FOLDER_PATH withIntermediateDirectories:YES attributes:nil error:nil];
        }
        _videoFileName = videoFileName;
        LYLog(@"%@",outputFilePath);
        NSURL *fileUrl = [NSURL fileURLWithPath:outputFilePath];
        _videoFilePath = fileUrl.relativeString;
        [self.captureMovieFileOuput startRecordingToOutputFileURL:fileUrl recordingDelegate:self];
    }else{
        [self.captureMovieFileOuput stopRecording];//停止录制
    }
}

#pragma mark 切换前后摄像头
- (void)changeVideoCameraPositionAction:(UIButton *)sender{
    AVCaptureDevice *currentDevice = [self.captureDeviceInput device];
    AVCaptureDevicePosition currentPosition = [currentDevice position];
    [self removeNotificationFromCaptureDevice:currentDevice];
    AVCaptureDevice *tochangeDevice;
    AVCaptureDevicePosition toChangePosition = AVCaptureDevicePositionFront;
    if (currentPosition == AVCaptureDevicePositionUnspecified || currentPosition == AVCaptureDevicePositionFront) {
        toChangePosition = AVCaptureDevicePositionBack;
    }
    tochangeDevice = [self getCameraDeviceWithPosition:toChangePosition];
    //获得要调整的设备输入对象
    AVCaptureDeviceInput *tochangeDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:tochangeDevice error:nil];
    //改变会话的配置一定要先开启配置,配置完成后提交配置改变
    [self.captureSession beginConfiguration];
    //移除原有的输入对象
    [self.captureSession removeInput:self.captureDeviceInput];
    //添加新的输入对象
    if ([self.captureSession canAddInput:tochangeDeviceInput]) {
        [self.captureSession addInput:tochangeDeviceInput];
        self.captureDeviceInput = tochangeDeviceInput;
    }
    //提交会话配置
    [self.captureSession commitConfiguration];
}


#pragma mark 视频输出代理
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections{
    NSLog(@"%s",__FUNCTION__);

}

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{
    LYLog(@"%s",__FUNCTION__);
    if (_isCancel) {
        return;
    }
//    self.enableRotation = YES;
    if (_isRemovePath) {
        NSError *error = nil;
        [[NSFileManager defaultManager] removeItemAtURL:outputFileURL error:&error];
        if (!error) {
            NSLog(@"--取消发送删除录制视频成功----%@",error);
        }
        [self dismissViewControllerAnimated:YES completion:nil];
    }else{
        UIBackgroundTaskIdentifier lastBackgroundTaskIndentifier = self.backgroundTaskIdentifier;
        self.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
        if (lastBackgroundTaskIndentifier!=UIBackgroundTaskInvalid) {
            [[UIApplication sharedApplication] endBackgroundTask:lastBackgroundTaskIndentifier];
        }
        [self dismissViewControllerAnimated:YES completion:^{
            self.finishRecordBlock(outputFileURL,self->_videoFileName);
        }];
    }
    
}


- (void)recordVideoFinishedBlock:(recordVideoDidFinishedBlock)block{
    self.finishRecordBlock = block;
}


- (void)removeNotificationFromCaptureDevice:(AVCaptureDevice *)captureDevice{
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}




- (void)dealloc{
    [self.captureSession stopRunning];
    self.captureSession = nil;
    self.captureDeviceInput = nil;
    self.captureMovieFileOuput = nil;
    [self.captureVideoPreViewLayer removeFromSuperlayer];
}






//获取指定位置摄像头
- (AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition)position{
    NSArray *cameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *camera in cameras) {
        if ([camera position] == position) {
            return camera;
        }
    }
    return nil;
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end
